package com.jt.service;

import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.datatransfer.FlavorEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Service
@PropertySource(value = "classpath:/properties/image.properties",
        encoding = "UTF-8") //将配置文件导入容器
public class FileServiceImpl implements FileService{

    @Value("${image.fileDir}")
    private String fileDir;     // = "D:/JT-SOFT/images";
    @Value("${image.urlPath}")
    private String urlPath;     //设定域名地址

    private static Set<String> typeSet = new HashSet<>();
    static {
        //利用配置文件动态将图片类型获取.
        typeSet.add(".jpg");
        typeSet.add(".png");
        typeSet.add(".gif");
    }


    /**
     * 业务逻辑:实现文件上传
     * 步骤:
     *      1.校验图片的类型  jpg|png|gif.......
     *      2.校验文件是否为恶意程序...
     *      3.采用分目录的结构进行存储
     *      4.避免文件重名  UUID
     *
     * 考题: UUID有多少种排列组合? 32位16进制数.... 0-9 A-F   2^4*32 2^128   hash碰撞
     *       hash取值有多少种可能性? 8位16进制数    2^32
     *
     * @param uploadFile
     * @return
     */
    @Override
    public ImageVO upload(MultipartFile uploadFile){
        //一. 校验图片类型  1.利用集合校验   2.正则表达式
        //1.1 获取文件名称  1.jpg  1.JPG
        String fileName = uploadFile.getOriginalFilename();
        fileName = fileName.toLowerCase();
        int index = fileName.lastIndexOf(".");
        //1.2 获取下标 获取文件后缀类型
        String fileType = fileName.substring(index);
        //1.3 判断是否为图片类型
        if(!typeSet.contains(fileType)){
            return ImageVO.fail();
        }

        //二.如果是图片  高度/宽度
        //2.1将数据转化为图片对象
        try {
            BufferedImage bufferedImage =
                    ImageIO.read(uploadFile.getInputStream());
            int width  = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();

            if(width == 0 || height == 0){
                return ImageVO.fail();
            }

            //三 实现分目录存储
            //3.1按照/yyyy/MM/dd/的方式进行目录划分
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
                    .format(new Date());
            //D:/JT-SOFT/images/2020/12/1/
            String fileDirPath = fileDir + dateDir;
            File dirFile = new File(fileDirPath);
            //3.2 创建目录
            if(!dirFile.exists()){
                dirFile.mkdirs();
            }

            //四. 实现文件上传 20-18-3.3
            //4.1 准备文件名称  UUID  522f88bb-33b2-11eb-93fb-00d861eaf238
            String uuid = UUID.randomUUID()
                    .toString().replace("-", "");
            //4.2 动态生成文件名称  uuid.jpg
            String uuidName = uuid + fileType;

            //4.3 实现文件上传  D:\JT-SOFT\images\2020\12\02\a.jpg
            File realFile = new File(fileDirPath+uuidName);
            uploadFile.transferTo(realFile);

            //本地磁盘地址:       D:\JT-SOFT\images\2020\12\02\a.jpg
            //网络访问虚拟地址:   http://image.jt.com\2020\12\02\a.jpg
            String url =  urlPath + dateDir + uuidName;
            return ImageVO.success(url, width,height);

        } catch (IOException e) {
            e.printStackTrace();
            return ImageVO.fail(); //报错返回
        }
    }
}